home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / UTIL / MEMORY / OLD / MEM208SRC / !Memphis / c / sprstore < prev   
Text File  |  1993-09-08  |  7KB  |  311 lines

  1. /*
  2.  * sprstore.c
  3.  * Part of the !Memphis distribution
  4.  * (c) bdb/nas, 1991-3
  5.  */
  6.  
  7. /* #define DEBUG */
  8. /* includes */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "kernel.h"
  13. #include "swis.h"
  14. #include "sprite.h"
  15. #include "util.h"
  16. #include "core.h"
  17. #include "spr.h"
  18. #include "Lfile.h"
  19.  
  20. #include "store.h"
  21.  
  22. /* debug support */
  23. #ifdef DEBUG
  24. #define DEBUGF printf
  25. #else
  26. #define DEBUGF 1?(void)0:(void)printf
  27. #endif
  28.  
  29. /* vars */
  30. #define ROOTFILETYPE 0x3F1              /* Acorn-allocated */
  31.  
  32. #define STOREHANDBUFSIZE 10
  33.  
  34. /* storeid will be NULL for sprite area, or else a ptr to this */
  35.  
  36. struct storeid
  37. { char basename[256];
  38.   LHANDLE storehandle[STOREHANDBUFSIZE];   /* OS file handle */
  39.   int storeinode[STOREHANDBUFSIZE];    /* inode number or -1 */
  40.   int nextone;
  41.   storeid next;
  42. };
  43.  
  44. static storeid thestoreids;
  45.  
  46. static DEFERR( mb_Lostsprite,           0,  "sprite lost" );
  47. static DEFERR( mb_Lostfile,             0,  "host file lost" );
  48.  
  49. /*
  50.  * store interface part defines 
  51.  */
  52. typedef struct file_header
  53. {       sprite_header   h;
  54.         char    data[4];
  55. } file_header;
  56.  
  57. /*
  58.  * Root Lfile header
  59.  */
  60. typedef struct root_header
  61. {
  62.   char id[4];   /* "MemF" */
  63.   char ctype;   /* compression type, 1 = squash */
  64.   char res1;    /* reserved, must be 0 */
  65.   char res2;
  66.   char res3;
  67. } root_header;
  68.  
  69. #define FHSIZE ( sizeof( file_header )-4 )
  70. #define ASERROR ==_kernel_ERROR?_kernel_last_oserror():NULL
  71.  
  72.  
  73. static file_header *findstoresprite( int inode ) /* Find sprite for an inode*/
  74. { SPRITENAME sname;
  75.   sprintf( sname.name, "mfs%08x", inode );
  76.   return (file_header *)findsprite( sname );
  77. }
  78.  
  79. static char *storename(storeid s,int inode ) /* Make host file name for an inode*/
  80. { static char buf[256],*b1;
  81.   strcpy(buf,s->basename);
  82.   b1 = strrchr(buf,';');
  83.   if (b1)
  84.   { *b1 = ':';
  85.     if (b1>buf && b1[-1]==';')
  86.       b1[-1]=':';
  87.   }
  88.   b1=buf+strlen(buf);
  89.   while (inode>0)
  90.   { char b[4];
  91.     sprintf(b,",.%c","0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[inode%36]);
  92.     strins(b1,b);
  93.     inode/=36;
  94.   }
  95.   return buf;
  96. }
  97.  
  98. static int storefindh( storeid s,int inode ) /* Open host file for an inode*/
  99. { char *p;
  100.   int n;
  101.   for (n=0;n<STOREHANDBUFSIZE;n++)
  102.     if (s->storeinode[n]==inode)
  103.       return n;
  104.   n = s->nextone;
  105.   if (++s->nextone>=STOREHANDBUFSIZE)
  106.     s->nextone=0;
  107.   if (s->storeinode[n]!=-1 && s->storehandle[n])
  108.     Lclose(s->storehandle[n]);
  109.   p=storename(s,inode);
  110.   if (Lopen(p,&s->storehandle[n]))
  111.     s->storehandle[n]=NULL;
  112.   s->storeinode[n]=inode;
  113. DEBUGF("storefindhand(%d),%s=%d\n",inode,p,n);
  114.   return n;
  115. }
  116.  
  117. static LHANDLE storefindhand( storeid s,int inode ) /* Open host file for an inode*/
  118. {
  119.   return s->storehandle[storefindh(s,inode)];
  120. }
  121.  
  122. _kernel_oserror *Store_Init(void) /* Initialise store subsystem*/
  123. {
  124.   DEBUGF("Store_Init\n");
  125.   thestoreids = NULL;
  126.   return Linit();
  127. }
  128.  
  129. void Store_Flush(void)
  130. { storeid s,t;
  131.   for (s=thestoreids;s;s=t)
  132.   { int i;
  133.     for (i=0;i<STOREHANDBUFSIZE;i++)
  134.     { if (s->storeinode[i]!=-1 && s->storehandle[i])
  135.         Lclose(s->storehandle[i]);
  136.       s->storeinode[i]=-1;
  137.     }
  138.     t = s->next;
  139.   }
  140. }
  141.  
  142. _kernel_oserror *Store_Finish(void) /* Terminate store subsystem*/
  143. { storeid s,t;
  144.   Store_Flush();
  145.   for (s=thestoreids;s;s=t)
  146.   { t = s->next;
  147.     free(s);
  148.   }
  149.   thestoreids = NULL;
  150.   return Lfinish();
  151. }
  152.  
  153. storeid Store_Find( char *special_field, char *volume ) /* Find a storeid*/
  154. { storeid s;
  155.   int i;
  156.   volume = volume;
  157.   DEBUGF("Store_Find %s %s\n",special_field?special_field:"NULL",volume?volume:"NULL");
  158.   if (!special_field)
  159.     return NULL;
  160.   for (s=thestoreids;s;s=s->next)
  161.     if (!strcmp(s->basename,special_field))
  162.       return s;
  163.   s = calloc(1,sizeof(struct storeid));
  164.   strcpy(s->basename,special_field);
  165.   for (i=0;i<STOREHANDBUFSIZE;i++)
  166.     s->storeinode[i]=-1;
  167.   s->next = thestoreids;
  168.   s->nextone = 0;
  169.   thestoreids = s;
  170.   return s;
  171. }
  172.  
  173. _kernel_oserror *Store_Read(storeid s, int inode, int offset, int length, void *ptr) 
  174. {
  175.   DEBUGF("Store_Read(%s,%d,%d,%d,%p)\n",s?s->basename:"Mem",inode,offset,length,ptr);
  176.   if (s)
  177.   { LHANDLE p=storefindhand(s,inode);
  178.     if (!p)
  179.       return ERR(mb_Lostfile);
  180.     return Lread(p,offset,length,ptr);
  181.   }
  182.   else
  183.   { file_header *h=findstoresprite(inode);
  184.     if (!h)
  185.       return ERR(mb_Lostsprite);
  186.     memcpy( ptr, &h->data[offset], length );
  187.     return NULL;
  188.   }
  189. }
  190.  
  191. _kernel_oserror *Store_Write(storeid s,int inode, int offset, int length, void *ptr )
  192. {
  193.   DEBUGF("Store_Write(%s,%d,%d,%d,%p)\n",s?s->basename:"Mem",inode,offset,length,ptr);
  194.   if (s)
  195.   { LHANDLE p=storefindhand(s,inode);
  196.     if (!p)
  197.       return ERR(mb_Lostfile);
  198.     return Lwrite(p,offset,length,ptr);
  199.   }
  200.   else
  201.   { file_header *h=findstoresprite(inode);
  202.     if (!h)
  203.       return ERR(mb_Lostsprite);
  204.     memcpy( &h->data[offset], ptr, length );
  205.     return NULL;
  206.   }
  207. }
  208.  
  209. _kernel_oserror *Store_SetLength( storeid s,int inode, int length )
  210. { DEBUGF("Store_SetLength(%s,%d,%d)\n",s?s->basename:"Mem",inode,length);
  211.   if (s)
  212.   { int n=storefindh(s,inode);
  213.     _kernel_osfile_block b;
  214.     if (length==0)
  215.     { if (s->storehandle[n])
  216.       { Lclose(s->storehandle[n]);
  217.         s->storehandle[n]=0;
  218.         return _kernel_osfile(6,storename(s,inode),&b) ASERROR;
  219.       }
  220.       else
  221.         return NULL;
  222.     }
  223.     else
  224.     { int h=storefindh(s,inode);
  225.       if (s->storehandle[h])
  226.         return Lsetlength(s->storehandle[h],length);
  227.       else
  228.       { _kernel_oserror *err;
  229.         char *p,*n;
  230.         s->storeinode[h]=-1;
  231.         err = Lcreate(n=storename(s,inode),length);
  232.         if (err)
  233.         { for (p=n;*p;p++)
  234.             if (*p=='.')
  235.             { *p=0;
  236.               _kernel_osfile(8,n,&b);
  237.               *p='.';
  238.             }
  239.           err = Lcreate(n=storename(s,inode),length);
  240.         }
  241.         /* Create root inode */
  242.         if (!inode)
  243.         { root_header root;
  244.           b.load=ROOTFILETYPE;
  245.           _kernel_osfile(18,n,&b);
  246.           strcpy(root.id, "MemF");
  247.           root.ctype = 1; root.res1 = 0; root.res2 = 0; root.res3 = 0;
  248.         }
  249.         DEBUGF("Create %s len %d %s\n",n,length,err?"ERR":"OK");
  250.         return err;
  251.       }
  252.     }
  253.   }
  254.   else
  255.   {
  256.     file_header *h=findstoresprite( inode );
  257.     if (length==0)
  258.     { if (h)
  259.         deletesprite(&h->h);
  260.       return NULL;
  261.     }
  262.     else
  263.     { length = ((length-1)|127)+1;
  264.       if (h)
  265.         return setspritesize( &h->h, length+FHSIZE-SHSIZE );
  266.       else
  267.       { sprite_header *h;
  268.         SPRITENAME sname;
  269.         sprintf( sname.name, "mfs%08x", inode );
  270.         return createsprite( sname, length+FHSIZE-SHSIZE, &h );
  271.       }
  272.     }
  273.   }
  274. }
  275.  
  276. _kernel_oserror *Store_FreeSpace( storeid s, struct freespace *b )
  277. { _kernel_swi_regs r;
  278.   _kernel_oserror *err=NULL;
  279.   if (!s)
  280.     spritefreespace(b);
  281.   else
  282.   { r.r[0]=49;
  283.     r.r[1]=(int)storename(s,0);
  284.     err=_kernel_swi(OS_FSControl,&r,&r);
  285.     b->free=r.r[0];
  286.     b->biggest = r.r[1];
  287.     b->size = r.r[2];
  288.   }
  289.   return err;
  290. }
  291.  
  292. char * Store_Name( storeid s ) 
  293. { char *p;
  294.   if (!s)
  295.     return "Sprites";
  296.   p=strrchr(s->basename,'.');
  297.   if (p)
  298.     return p+1;
  299.   else
  300.     return s->basename;
  301. }
  302.  
  303. char * Store_SpecialField( storeid s ) 
  304. {
  305.   if (!s)
  306.     return NULL;
  307.   return s->basename;
  308. }
  309.  
  310.  
  311.